﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CTP;
using CTP.Entitys;


namespace CTPDemo4Net
{
    public partial class CTPtest : Form
    {
        private CCTP myCTPRequest;
        private CTPCallbackHandle myCTPCallback;
        private TradingAccount _myAccount;
        public TradingAccount myAccount
        {
            get
            {
                _myAccount.UserAccount = this.txtAccount.Text.Trim();
                _myAccount.Password = this.txtPassword.Text.Trim();
                _myAccount.BranchNO = this.txtBorker.Text.Trim();
                return _myAccount;
            }
        }
        private int requestID = 100;
        private List<Order> myOrderList;
        private List<InnerOrder> myInnerOrderList;
        public CTPtest()
        {
            InitializeComponent();
            myOrderList = new List<Order>();
            myInnerOrderList = new List<InnerOrder>();
            myCTPRequest = new CCTP();
            myCTPCallback = new CTPCallbackHandle();
            _myAccount = new TradingAccount();
            myCTPRequest.RegisterCallback(myCTPCallback);
            myCTPCallback.OnCallbackEvent += new EventHandler<CTPEventArgs>(myCTPCallback_OnCallbackEvent);
            myCTPCallback.OnUpdateOrderStatus += new EventHandler<CTPEventArgs>(myCTPCallback_OnUpdateOrderStatus);
            Directory.CreateDirectory("log");

            cmbAccountSel.SelectedIndex = 0;
        }

        private void CTPtest_Load(object sender, EventArgs e)
        {
            this.dataGridView1.AutoGenerateColumns = false;

        }

        void myCTPCallback_OnUpdateOrderStatus(object sender, CTPEventArgs e)  //更新单状态
        {
            if (e.EventName == "OnOrderFilled")   //成交回报
            {
                //Order order = myOrderList.Find(p => p.OrderRef == e.orderreport.OrderRef);
                InnerOrder order = myInnerOrderList.Find(p =>
                    (p.OrderRef == e.orderreport.OrderRef && !string.IsNullOrEmpty(p.OrderRef))
                    || (p.OrderID == e.orderreport.OrderID && !string.IsNullOrEmpty(p.OrderID)));
                if (order == null) //重启过
                {
                    InnerOrder orderNew = new InnerOrder();
                    orderNew.FilledAmount = e.orderreport.FilledQuantity;
                    orderNew.Message = e.orderreport.ToString();
                    orderNew.OrderID = e.orderreport.OrderID;
                    orderNew.Account = e.orderreport.Account;
                    orderNew.Price = e.orderreport.Price;
                    myInnerOrderList.Add(orderNew);
                    myOrderList.Add(ConvertToOrder(orderNew));
                }
                order.OrderID = e.orderreport.OrderID;
                order.FilledAmount = e.orderreport.FilledQuantity;
                order.Message = e.strBuilder.ToString();
                order.Price = e.orderreport.Price;
            }
            else if (e.EventName == "OnOrderStatus")  //委托单状态回报
            {
                //Order order = myOrderList.Find(p => p.OrderRef == e.orderstatus.OrderRef);
                InnerOrder order = myInnerOrderList.Find(p =>
                      (p.OrderRef == e.orderstatus.OrderRef && !string.IsNullOrEmpty(p.OrderRef))
                    || (p.OrderID == e.orderstatus.OrderID && !string.IsNullOrEmpty(p.OrderID)));
                if (order == null) //重启过
                {
                    InnerOrder orderNew = new InnerOrder();
                    orderNew.OrderState = e.orderstatus.OrderState;
                    orderNew.Message = e.strBuilder.ToString();
                    orderNew.OrderID = e.orderstatus.OrderID;
                    orderNew.Account = e.orderstatus.Account;
                    myInnerOrderList.Add(orderNew);
                    myOrderList.Add(ConvertToOrder(orderNew));

                }
                else
                {
                    order.OrderState = e.orderstatus.OrderState;
                    order.Message = e.strBuilder.ToString();
                    order.OrderID = e.orderstatus.OrderID;
                }
            }
            UpdateGridView();
        }

        void myCTPCallback_OnCallbackEvent(object sender, CTPEventArgs e)
        {
            if (this.rtxtMessage.InvokeRequired)
            {
                this.rtxtMessage.Invoke(new MethodInvoker(() =>
                    {
                        this.rtxtMessage.Text += e.strBuilder.ToString() + "\r\n";
                    }));
            }
            else
            {
                this.rtxtMessage.Text += e.strBuilder.ToString() + "\r\n";
            }
        }
        private void btnLogin_Click(object sender, EventArgs e)  //登陆
        {
            TradingAccount acc = myAccount;
            int result = myCTPRequest.Login(acc, requestID);
            requestID++;
        }

        private void btnLogOut_Click(object sender, EventArgs e)  //登出
        {
            myCTPRequest.Logout(myAccount, requestID);
            //登出
            requestID++;
        }

        private void button8_Click(object sender, EventArgs e) //查账户概览
        {
            myCTPRequest.QueryAccountSummary(myAccount, requestID);
            requestID++;
        }

        private void button2_Click(object sender, EventArgs e) //查结算信息
        {
            myCTPRequest.QuerySettlement(myAccount, requestID);
            requestID++;

        }

        private void button1_Click(object sender, EventArgs e) //确认结算信息
        {
            myCTPRequest.ConfirmSettlement(myAccount, requestID);
            requestID++;
        }

        private void button9_Click(object sender, EventArgs e) //查持仓情况
        {
            myCTPRequest.QueryPosition(myAccount, requestID);
            requestID++;
        }

        private void button10_Click(object sender, EventArgs e) //查当日委托
        {
            PageInfo page = new PageInfo();
            myCTPRequest.QueryTodayOrder(myAccount, page, requestID);
            requestID++;
        }

        private void button12_Click(object sender, EventArgs e) //查当日成交
        {
            PageInfo page = new PageInfo();
            myCTPRequest.QueryTodayFilled(myAccount, page, requestID);
            requestID++;
        }

        private void button11_Click(object sender, EventArgs e) //查历史委托
        {

        }

        private void button3_Click(object sender, EventArgs e) //下单
        {
            Order myOrder = new Order();
            myOrder.Code = txtSymbol.Text;
            myOrder.UserAccount = myAccount.UserAccount;
            myOrder.OpenClose = (OpenClose)Enum.Parse(typeof(OpenClose), cmbOpenClose.Text);
            myOrder.Side = (Side)Enum.Parse(typeof(Side), cmbSide.Text);
            myOrder.Unit = Unit.Hand;
            myOrder.OrderRef = requestID.ToString();
            myOrder.Amount = double.Parse(txtAmount.Text);
            myOrder.Price = (checkPrice.Checked) ? 0 : double.Parse(this.txtPrice.Text);
            myOrder.HedgeFlag = HedgeFlag.Speculation;
            myCTPRequest.PlaceOrder(myAccount, myOrder, requestID);
            requestID++;

            myOrderList.Add(myOrder);
            myInnerOrderList.Add(ConvertToInnerOrder(myOrder));
            UpdateGridView();
        }

        private void button4_Click(object sender, EventArgs e) //撤单
        {
        	CancelOrderInfo info = new CancelOrderInfo();
        	info.ExchangeID = "SHFE";
        	info.OrderID = this.txtOrderID.Text;
        	//info.OrderActionRef = 
        	myCTPRequest.CancelOrder(myAccount,info,100);
        }


        private void UpdateGridView()
        {
            List<InnerOrder> innerOrderList = new List<InnerOrder>();

            //foreach (Order order in myOrderList)
            //{
            //    innerOrderList.Add(ConvertToInnerOrder(order));
            //}
            foreach (InnerOrder order in myInnerOrderList)
            {
                innerOrderList.Add(order);
            }
            if (this.dataGridView1.InvokeRequired)
            {
                this.dataGridView1.Invoke(new MethodInvoker(() =>
                    {
                        this.dataGridView1.DataSource = innerOrderList;
                        this.dataGridView1.Refresh();
                    }));
            }
            else
            {
                this.dataGridView1.DataSource = innerOrderList;
                this.dataGridView1.Refresh();
            }

        }

        private InnerOrder ConvertToInnerOrder(Order order)
        {
            InnerOrder inorder = new InnerOrder();
            inorder.Account = order.UserAccount;
            inorder.Symbol = order.Code;
            inorder.OrderID = order.OrderID;
            inorder.Side = order.Side;
            inorder.OpenClose = order.OpenClose;
            inorder.Amount = order.Amount;
            inorder.Unit = order.Unit;
            inorder.OrderState = order.OrderState;
            inorder.OrderRef = order.OrderRef;
            inorder.FilledAmount = order.FilledAmount;
            inorder.OrderRef = order.OrderRef;

            return inorder;
        }
        private Order ConvertToOrder(InnerOrder innerorder)
        {
            Order order = new Order();
            order.UserAccount = innerorder.Account;
            order.Code = innerorder.Symbol;
            order.OrderID = innerorder.OrderID;
            order.Side = innerorder.Side;
            order.OpenClose = innerorder.OpenClose;
            order.Amount = innerorder.Amount;
            order.Unit = innerorder.Unit;
            order.OrderState = innerorder.OrderState;
            order.OrderRef = innerorder.OrderRef;
            order.FilledAmount = innerorder.FilledAmount;

            return order;
        }

        private void btnLoginQuote_Click(object sender, EventArgs e)
        {
            int result = myCTPRequest.LoginQoute(myAccount, requestID);
            requestID++;
        }

        private void btnLogoutQoute_Click(object sender, EventArgs e)
        {

            int result = myCTPRequest.LogoutQoute(myAccount, requestID);
            requestID++;
        }

        private void btnSub_Click(object sender, EventArgs e)
        {
            string[] codes = txtCodes.Text.Replace("\r\n", "").Split(',');
            int result = myCTPRequest.SubscribeQoute(codes);
            int a = result;
        }

        private void btnUnSub_Click(object sender, EventArgs e)
        {
            string[] codes = txtCodes.Text.Replace("\r\n", "").Split(',');
            int result = myCTPRequest.UnSubscribeQoute(codes);
        }

        private void cmbAccountSel_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.txtAccount.Text = "00000088" ;//+ cmbAccountSel.Text;
            this.txtPassword.Text = "123456";
            this.txtBorker.Text = "1023";
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            rtxtMessage.Text = "";
        }

        private void btnClearOrder_Click(object sender, EventArgs e)
        {
            myInnerOrderList.Clear();
            myOrderList.Clear();
            UpdateGridView(); 
        }
    }

    public class InnerOrder
    {

        public string Account { get; set; }

        public string Symbol { get; set; }

        public string OrderID { get; set; }

        public Side Side { get; set; }

        public OpenClose OpenClose { get; set; }

        public double Amount { get; set; }

        public Unit Unit { get; set; }

        public OrderState OrderState { get; set; }

        public string OrderRef { get; set; }

        public double FilledAmount { get; set; }

        public string Message { get; set; }

        public double Price { get; set; }

    }
}
